-include common.mk

#
# Input arguments:
# 	$(META_SRCDIRS)		- The full path of meta source files (.meta.S)
# 	$(META_INCDIRS)		- The full path of header files (.h)
#	$(META_CC)			- C compiler, It requires preprocessing parameters (e.g. -E -P)
#	$(BOARDPATH)		- The board path
#

# -------- parameters checkout

ifeq ($(META_SRCDIRS),)
$(error META_SRCDIRS should not be null)
endif
ifeq ($(META_INCDIRS),)
$(error META_INCDIRS should not be null)
endif
ifeq ($(META_CC),)
$(error META_CC should not be null)
endif
ifeq ($(BOARDPATH),)
$(error BOARDPATH should not be null)
endif

# -------- verbose contorl, `make V=1` to show the detail of compile

# the absolute path of matrix
ROOTPATH			:= $(abspath ./)

# note: must use the `=` instead of `:=` because of $</$@
SILENT				 = @
MSG					 = @echo META: $(subst $(ROOTPATH)/,,$<)
ifeq ("$(origin V)", "command line")
	ifeq ($(V),1)
SILENT	 			 =
MSG	 				 =
	endif
endif

# -------- makefile's arguments

META_SUFFIX			?= meta.S

# -------- the meta source files of kernel

META_SRCDIRS		+= $(ROOTPATH)/arch
META_SRCDIRS		+= $(ROOTPATH)/driver
META_SRCDIRS		+= $(ROOTPATH)/filesystem
META_SRCDIRS		+= $(ROOTPATH)/itc
META_SRCDIRS		+= $(ROOTPATH)/memory
META_SRCDIRS		+= $(ROOTPATH)/portable
META_SRCDIRS		+= $(ROOTPATH)/shell
META_SRCDIRS		+= $(ROOTPATH)/system
META_SRCDIRS		+= $(ROOTPATH)/task
META_SRCDIRS		+= $(ROOTPATH)/utils
META_SRCDIRS		+= $(ROOTPATH)/kprocess
META_SRCDIRS		+= $(ROOTPATH)/testbench

# -------- generate target file full path

# check whether the board folder contain matrix
ISCONTAIN_MX		:= $(and $(filter $(BOARDPATH)/%,$(ROOTPATH)),$(if $(filter $(BOARDPATH),$(ROOTPATH)),,yes))

# get the source files in `META_SRCDIRS`
METAFILES			:= $(foreach dir,$(META_SRCDIRS),$(wildcard $(dir)/*.$(META_SUFFIX)))

ifeq ($(ISCONTAIN_MX),yes)
# generate kernel objects (must be first)
METAOBJS			:= $(patsubst $(ROOTPATH)/%.$(META_SUFFIX),$(BOARDPATH)/meta/%,$(METAFILES))
# generate board objects
METAOBJS			:= $(patsubst $(BOARDPATH)/%.$(META_SUFFIX),$(BOARDPATH)/meta/board/%,$(METAOBJS))
else
# generate board objects (must be first)
METAOBJS			:= $(patsubst $(BOARDPATH)/%.$(META_SUFFIX),$(BOARDPATH)/meta/board/%,$(METAFILES))
# generate kernel objects
METAOBJS			:= $(patsubst $(ROOTPATH)/%.$(META_SUFFIX),$(BOARDPATH)/meta/%,$(METAOBJS))
endif

# -------- the include path for meta files

META_INCDIRS		+= $(ROOTPATH)/portable
META_INCDIRS		:= $(subst $(ROOTPATH)/,,$(META_INCDIRS))
I					:= $(foreach dir,$(META_INCDIRS),-I$(dir))

# -------- rules

# set default target
.DEFAULT_GOAL		:= ALL

# target files (a collection)
ALL : $(METAOBJS)

# board object files (must be first)
$(BOARDPATH)/meta/board/% : $(BOARDPATH)/%.$(META_SUFFIX)
	$(MSG)
	$(SILENT) mkdir -p $(@D)
	$(SILENT) $(META_CC) $(I) -o $@ $<

# kernel object files
$(BOARDPATH)/meta/% : %.$(META_SUFFIX)
	$(MSG)
	$(SILENT) mkdir -p $(@D)
	$(SILENT) $(META_CC) $(I) -o $@ $<

# -------- pseudo target

.PHONY: clean

clean:
	$(SILENT)rm -rf $(BOARDPATH)/meta/*
